package com.little.g.springcloud.mall.service;

import com.little.g.springcloud.common.utils.CharUtil;
import com.little.g.springcloud.mall.api.LitemallStorageService;
import com.little.g.springcloud.mall.api.StorageService;
import com.little.g.springcloud.mall.config.StorageProperties;
import com.little.g.springcloud.mall.dto.LitemallStorageDTO;
import com.little.g.springcloud.mall.storage.*;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;

import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.stream.Stream;

/**
 * 提供存储服务类，所有存储服务均由该类对外提供
 */
@Service(protocol = "dubbo")
public class StorageServiceImpl implements StorageService {

	@Autowired
	private StorageProperties properties;

	private String active;

	private Storage storage;

	@PostConstruct
	public void init() {
		String active = this.properties.getActive();
		this.setActive(active);
		if (active.equals("local")) {
			setStorage(localStorage());
		}
		else if (active.equals("aliyun")) {
			setStorage(aliyunStorage());
		}
		else if (active.equals("tencent")) {
			setStorage(tencentStorage());
		}
		else if (active.equals("qiniu")) {
			setStorage(qiniuStorage());
		}
		else {
			throw new RuntimeException("当前存储模式 " + active + " 不支持");
		}
	}

	public LocalStorage localStorage() {
		LocalStorage localStorage = new LocalStorage();
		StorageProperties.Local local = this.properties.getLocal();
		localStorage.setAddress(local.getAddress());
		localStorage.setStoragePath(local.getStoragePath());
		return localStorage;
	}

	public AliyunStorage aliyunStorage() {
		AliyunStorage aliyunStorage = new AliyunStorage();
		StorageProperties.Aliyun aliyun = this.properties.getAliyun();
		aliyunStorage.setAccessKeyId(aliyun.getAccessKeyId());
		aliyunStorage.setAccessKeySecret(aliyun.getAccessKeySecret());
		aliyunStorage.setBucketName(aliyun.getBucketName());
		aliyunStorage.setEndpoint(aliyun.getEndpoint());
		return aliyunStorage;
	}

	public TencentStorage tencentStorage() {
		TencentStorage tencentStorage = new TencentStorage();
		StorageProperties.Tencent tencent = this.properties.getTencent();
		tencentStorage.setSecretId(tencent.getSecretId());
		tencentStorage.setSecretKey(tencent.getSecretKey());
		tencentStorage.setBucketName(tencent.getBucketName());
		tencentStorage.setRegion(tencent.getRegion());
		return tencentStorage;
	}

	public QiniuStorage qiniuStorage() {
		QiniuStorage qiniuStorage = new QiniuStorage();
		StorageProperties.Qiniu qiniu = this.properties.getQiniu();
		qiniuStorage.setAccessKey(qiniu.getAccessKey());
		qiniuStorage.setSecretKey(qiniu.getSecretKey());
		qiniuStorage.setBucketName(qiniu.getBucketName());
		qiniuStorage.setEndpoint(qiniu.getEndpoint());
		return qiniuStorage;
	}

	@Autowired
	private LitemallStorageService litemallStorageService;

	public String getActive() {
		return active;
	}

	public void setActive(String active) {
		this.active = active;
	}

	public Storage getStorage() {
		return storage;
	}

	public void setStorage(Storage storage) {
		this.storage = storage;
	}

	/**
	 * 存储一个文件对象
	 * @param inputStream 文件输入流
	 * @param contentLength 文件长度
	 * @param contentType 文件类型
	 * @param fileName 文件索引名
	 */
	@Override
	public LitemallStorageDTO store(InputStream inputStream, long contentLength,
			String contentType, String fileName) {
		String key = generateKey(fileName);
		storage.store(inputStream, contentLength, contentType, key);

		String url = generateUrl(key);
		LitemallStorageDTO storageInfo = new LitemallStorageDTO();
		storageInfo.setName(fileName);
		storageInfo.setSize((int) contentLength);
		storageInfo.setType(contentType);
		storageInfo.setKey(key);
		storageInfo.setUrl(url);
		litemallStorageService.add(storageInfo);

		return storageInfo;
	}

	private String generateKey(String originalFilename) {
		int index = originalFilename.lastIndexOf('.');
		String suffix = originalFilename.substring(index);

		String key = null;
		LitemallStorageDTO storageInfo = null;

		do {
			key = CharUtil.getRandomString(20) + suffix;
			storageInfo = litemallStorageService.findByKey(key);
		}
		while (storageInfo != null);

		return key;
	}

	public Stream<Path> loadAll() {
		return storage.loadAll();
	}

	public Path load(String keyName) {
		return storage.load(keyName);
	}

	@Override
	public Resource loadAsResource(String keyName) {
		return storage.loadAsResource(keyName);
	}

	public void delete(String keyName) {
		storage.delete(keyName);
	}

	private String generateUrl(String keyName) {
		return storage.generateUrl(keyName);
	}

}
